package com.loeng.module.system.service.permission;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.loeng.module.system.dal.dataobject.permission.RoleDO;
import com.loeng.module.system.dal.mysql.permission.RoleMapper;
import com.loeng.module.system.dal.redis.RedisKeyConstants;
import com.loeng.module.system.enunms.RoleCodeEnum;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.loeng.framework.common.util.collection.CollectionUtils.convertList;

/**
 * 角色实现类
 * @author loeng zhuo
 */
@Service
public class RoleServiceImpl implements RoleService{

    @Resource
    private RoleMapper roleMapper;

    /**
     * 根据角色id获取角色列表
     * @param roleIds 角色id集合
     * @return 角色列表
     */
    @Override
    public List<RoleDO> getRoleList(Set<Long> roleIds) {
        if (CollectionUtil.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        return roleMapper.selectBatchIds(roleIds);
    }

    /**
     * 获得角色，从缓存中
     *
     * @param id 角色编号
     * @return 角色
     */
    @Override
    @Cacheable(value = RedisKeyConstants.ROLE, key = "#id",
            unless = "#result == null")
    public RoleDO getRoleFromCache(Long id) {
        return roleMapper.selectById(id);
    }

    /**
     * 是否有超管角色
     * @param roleIds 角色id集合
     * @return 是否有超管角色
     */
    @Override
    public boolean hasAnySuperAdmin(Set<Long> roleIds) {
        if (CollectionUtil.isEmpty(roleIds)) {
            return false;
        }
        RoleServiceImpl self = getSelf();
        return roleIds.stream().anyMatch(id -> {
            RoleDO role = self.getRoleFromCache(id);
            return role != null && RoleCodeEnum.isSuperAdmin(role.getCode());
        });
    }

    /**
     * 获得角色数组，从缓存中
     *
     * @param ids 角色编号数组
     * @return 角色数组
     */
    @Override
    public List<RoleDO> getRoleListFromCache(Collection<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        RoleServiceImpl self = getSelf();
        return convertList(ids, self::getRoleFromCache);
    }

    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private RoleServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }

}
